package com.adee.secure;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 消息摘要算法（哈希算法、指纹算法、散列算法）
 *
 * 名称      安全性    速度     摘要长度
 * SHA-256  高       慢       256位
 * SHA-1    高       慢       160位
 * MD5      中       快       128位
 *
 * MD5容易被暴力破解，推荐使用SHA1或更高强度的SHA256
 * SHA1也已被攻破，一般场合使用SHA1
 * 数字加密货币使用SHA256，比如比特币
 */
public class Test005_Digest {
    static final String str = "hello, 山高那个路远，也能获得~~";
    static byte[] bytes = str.getBytes(StandardCharsets.UTF_8);

    public static void main(String[] args) throws NoSuchAlgorithmException {
        testMD5();
        testSHA1();
        testSHA256();
    }

    // 返回十六进制MD5哈希码
    public static String MD5(byte[] content) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(content);
        byte[] digest = md.digest();
        return toHexString(digest);
    }

    public static void testMD5() throws NoSuchAlgorithmException {
        System.out.println("MD5: ");
        String s = MD5(bytes);
        System.out.println(s);
        String s1 = DigestUtils.md5Hex(bytes);
        System.out.println(s1);
        System.out.println(s1.equals(s));
    }

    // 返回十六进制SHA1哈希码
    public static String SHA1(byte[] content) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        md.update(content);
        byte[] digest = md.digest();
        return toHexString(digest);
    }

    public static void testSHA1() throws NoSuchAlgorithmException {
        System.out.println("SHA1: ");
        String s = SHA1(bytes);
        System.out.println(s);
        String s1 = DigestUtils.sha1Hex(bytes);
        System.out.println(s1);
        System.out.println(s1.equals(s));
    }

    // 返回十六进制SHA256哈希码
    public static String SHA256(byte[] content) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(content);
        byte[] digest = md.digest();
        return Hex.encodeHexString(digest);
    }

    public static void testSHA256() throws NoSuchAlgorithmException {
        System.out.println("SHA256: ");
        String s = SHA256(bytes);
        System.out.println(s);
        String s1 = Hex.encodeHexString(DigestUtils.sha256(bytes));
        System.out.println(s1);
        System.out.println(s1.equals(s));
    }

    /********************/
    public static String toHexString(byte[] bytes) {
        String[] arr = {
                "0","1","2","3","4","5","6","7",
                "8","9","a","b","c","d","e","f" };
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            sb.append(arr[(b & 0xff) >>> 4]).append(arr[b & 0xf]);
        }
        return sb.toString();
    }


}
